﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Xlit.Standard.Entity;

namespace Xlit.Standard.Data
{
    /// <summary>
    ///  仓储接口
    /// </summary>
    public interface IRepository : IDependency { }

    /// <summary>
    ///  仓储接口
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TPrimaryKey"></typeparam>
    public partial interface IRepository<TEntity, TPrimaryKey> : IRepository where TEntity : IEntity<TPrimaryKey>
    {
        /// <summary>
        ///  集合
        /// </summary>
        IQueryable<TEntity> Entities { get; }

        /// <summary>
        ///  判断集合是否为空
        /// </summary>
        /// <returns></returns>
        bool IsEmpty();
        /// <summary>
        ///  根据Id判断集合内是否存在
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        bool IsExist(TPrimaryKey primaryKey);
        /// <summary>
        ///  根据实体判断集合内是否存在
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        bool IsExist(TEntity entity);
        /// <summary>
        ///  根据条件判断集合内是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        bool IsExist(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  计算某个集的数量
        /// </summary>
        /// <returns></returns>
        long Count();
        /// <summary>
        ///  根据表达式计算数量
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        long Count(Expression<Func<TEntity, bool>> predicate);
       
        /// <summary>
        ///  取单个元素
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns>返回实体,若不存在返回null</returns>
        TEntity Single(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  获取符合条件的第一个元素
        /// </summary>
        /// <returns>返回实体,若不存在返回null</returns>
        TEntity First(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  根据主键获取实体
        ///  如不存在则返回Null
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        TEntity GetEntity(TPrimaryKey primaryKey);
        /// <summary>
        ///  根据条件获取集合IQueryable
        /// </summary>
        /// <returns></returns>
        IQueryable<TEntity> GetEntities(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  获取所有对象
        /// </summary>
        /// <returns></returns>
        IList<TEntity> GetList();
        /// <summary>
        ///  根据条件获取对象
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="include"></param>
        /// <returns></returns>
        IList<TEntity> GetList(Expression<Func<TEntity, bool>> predicate, string include = "");
       
        /// <summary>
        ///  添加一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        int Insert(TEntity entity);
        /// <summary>
        ///  批量添加实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Insert(IEnumerable<TEntity> entity);
        /// <summary>
        ///  更新一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        int Update(TEntity entity);
        /// <summary>
        ///  添加或更新一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        int InsertOrUpdate(TEntity entity);
        /// <summary>
        ///  根据Id进行删除
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        int Delete(TPrimaryKey primaryKey);
        /// <summary>
        ///  根据实体进行删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Delete(TEntity entity);
        /// <summary>
        ///  批量删除实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        int Delete(IEnumerable<TEntity> entity);
        /// <summary>
        ///  根据某一个条件批量删除
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        int Delete(Expression<Func<TEntity, bool>> predicate);
    }

    /// <summary>
    ///  仓储接口 异步
    /// </summary>
    /// <typeparam name="TEntity"></typeparam>
    /// <typeparam name="TPrimaryKey"></typeparam>
    public partial interface IRepository<TEntity, TPrimaryKey> : IRepository where TEntity : IEntity<TPrimaryKey>
    {
        /// <summary>
        ///  判断集合是否为空
        /// </summary>
        /// <returns></returns>
        Task<bool> IsEmptyAsync();
        /// <summary>
        ///  根据Id判断集合内是否存在
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<bool> IsExistAsync(TPrimaryKey primaryKey);
        /// <summary>
        ///  根据实体判断集合内是否存在
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<bool> IsExistAsync(TEntity entity);
        /// <summary>
        ///  根据条件判断集合内是否存在
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<bool> IsExistAsync(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  计算某个集的数量
        /// </summary>
        /// <returns></returns>
        Task<long> CountAsync();
        /// <summary>
        ///  根据表达式计算数量
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<long> CountAsync(Expression<Func<TEntity, bool>> predicate);

        /// <summary>
        ///  取单个元素
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<TEntity> SingleAsync(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  获取符合条件的第一个元素
        /// </summary>
        /// <returns></returns>
        Task<TEntity> FirstAsync(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        ///  根据主键获取实体
        ///  如不存在则返回Null
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<TEntity> GetEntityAsync(TPrimaryKey primaryKey);
        /// <summary>
        ///  获取所有对象
        /// </summary>
        /// <returns></returns>
        Task<IList<TEntity>> GetListAsync();
        /// <summary>
        ///  根据条件获取对象
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="include"></param>
        /// <returns></returns>
        Task<IList<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, string include = "");

        /// <summary>
        ///  添加一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<int> InsertAsync(TEntity entity);
        /// <summary>
        ///  批量添加实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> InsertAsync(IEnumerable<TEntity> entity);
        /// <summary>
        ///  更新一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<int> UpdateAsync(TEntity entity);
        /// <summary>
        ///  添加或更新一个实体
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<int> InsertOrUpdateAsync(TEntity entity);
        /// <summary>
        ///  根据Id进行删除
        /// </summary>
        /// <param name="primaryKey"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(TPrimaryKey primaryKey);
        /// <summary>
        ///  根据实体进行删除
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(TEntity entity);
        /// <summary>
        ///  批量删除实体
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(IEnumerable<TEntity> entities);
        /// <summary>
        ///  根据某一个条件批量删除
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        Task<int> DeleteAsync(Expression<Func<TEntity, bool>> predicate);
    }
}
